package org.zfes.snowier.cloud.zbss.asf;

import com.arcsoft.face.*;
import com.arcsoft.face.enums.DetectMode;
import com.arcsoft.face.enums.ImageFormat;

import javax.imageio.ImageIO;

import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.zfes.snowier.cloud.zbss.asf.biz.dto.ImageInfo;
import org.zfes.snowier.cloud.zbss.asf.biz.factory.FaceEngineFactory;
import org.zfes.snowier.cloud.zbss.asf.biz.util.ImageUtil;
import org.zfes.snowier.cloud.zbss.asf.engine.FaceEngineContainer;

import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FaceEngineTest3 {
	public static Integer threadPoolSize=2;
	
	public static   String appId = "NDdb9SB4WZHLmPxDVRPCQ5P2MAtghFqsaNarjCUpY5C";
	public static   String sdkKey = "6HgA3YoW7nsdh4F8Mr7vU9bhvyuxTmLbjUpkneTARiQY";
	private static Integer maxEngineSize=10;
    private static ExecutorService executorService;
    
    
    public static void main(String[] args) {
    	FaceEngineContainer container=FaceEngineContainer.getInstance(appId,sdkKey,maxEngineSize);
    	long start=System.currentTimeMillis();
    	new FaceEngineTest3().doTest(container);
    	long end=System.currentTimeMillis();
    	System.out.println("*****************"+(end-start));
    	
    }

    
    public  void doTest(FaceEngineContainer container) {
        executorService = Executors.newFixedThreadPool(threadPoolSize);
     
        for(int i=0;i<10;i++) {
        	executorService.submit(()->{
        		faceEngineTest(container);
        	});
        }
     


    }
    String path1= "D:\\12\\a.jpg";
    String path2= "D:\\12\\3-1.jpg";
    ImageInfo imageInfo = ImageUtil.getRGBData(new File(path1)).get();
    ImageInfo imageInfo2 = ImageUtil.getRGBData(new File(path2)).get();


    private void faceEngineTest(FaceEngineContainer container) {
    	long start=System.currentTimeMillis();
    	FaceEngine faceEngine1 = container.take().get();
    	FaceEngine faceEngine2 = container.take().get();
    	FaceEngine faceEngine3 = container.take().get();
    	FaceEngine faceEngine4 = container.take().get();
    	FaceEngine faceEngine5 = container.take().get();
    	try {
    		System.out.println("EngineQueueSize: "+container.getEngineQueueSize() );
    		    
    	        //人脸检测
    	        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
    	        int a=faceEngine1.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList);
    	        System.out.println("faceEngine.detectFaces-a:"+a);
    	        
    	        List<FaceInfo> faceInfoList2 = new ArrayList<FaceInfo>();
    	        int b=faceEngine2.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList2);
    	        System.out.println("faceEngine.detectFaces-b:"+b);
    	        //提取人脸特征
    	        FaceFeature faceFeature = new FaceFeature();
    	        int c=faceEngine3.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList.get(0), faceFeature);
    	        System.out.println("faceEngine.extractFaceFeature-c:"+c);
    	        
    	        FaceFeature faceFeature2 = new FaceFeature();
    	        int d=faceEngine4.extractFaceFeature(imageInfo2.getRgbData(), imageInfo2.getWidth(), imageInfo2.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList2.get(0), faceFeature2);
    	        System.out.println("faceEngine.extractFaceFeature-d:"+d);
    	        //人脸对比
    	        FaceFeature targetFaceFeature = new FaceFeature();
    	        targetFaceFeature.setFeatureData(faceFeature.getFeatureData());
    	       
    	        FaceFeature sourceFaceFeature = new FaceFeature();
    	        sourceFaceFeature.setFeatureData(faceFeature2.getFeatureData());

    	        FaceSimilar faceSimilar = new FaceSimilar();
    	        int e=faceEngine5.compareFaceFeature(targetFaceFeature, sourceFaceFeature, faceSimilar);
    	        System.out.println("faceEngine.compareFaceFeature-e:"+e+"||faceSimilar:"+faceSimilar.getScore());
    	        
    	        int processResult = faceEngine5.process(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList, FunctionConfiguration.builder().supportAge(true).supportFace3dAngle(true).supportGender(true).supportLiveness(true).build());
     	       
    	        //性别提取
    	        List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
    	        int genderCode = faceEngine5.getGender(genderInfoList);
    	        //年龄提取
    	        List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
    	        int ageCode = faceEngine5.getAge(ageInfoList);
    	        //3D信息提取
    	        List<Face3DAngle> face3DAngleList = new ArrayList<Face3DAngle>();
    	        int face3dCode = faceEngine5.getFace3DAngle(face3DAngleList);
    	        System.out.println(face3DAngleList);
    	        //活体信息
    	        List<LivenessInfo> livenessInfoList = new ArrayList<LivenessInfo>();
    	        int livenessCode = faceEngine5.getLiveness(livenessInfoList);
    	        System.out.println(livenessInfoList.get(0).getLiveness());
    	        
    	       
    	        System.out.println("||livenessCode:"+livenessCode);
    	       int liv= livenessInfoList.get(0).getLiveness();
    	     
    	        System.out.println("getLiveness:"+liv+"||livenessCode:"+livenessCode);
    	      
        } catch (Exception e) {
        	e.printStackTrace();
           
        } finally {
        	container.add(faceEngine1);
        	container.add(faceEngine2);
        	container.add(faceEngine3);
        	container.add(faceEngine4);
        	container.add(faceEngine5);

        }
    	long end=System.currentTimeMillis();
    	System.out.println("===================================="+(end-start));

     
    }
    

    public static void base666() {
    	base64StringToImage(s);
    }
    static String s="";
 static void base64StringToImage(String base64String) {
    	try {
    	byte[] bytes1 = Base64.getDecoder().decode(base64String);
    	ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
    	BufferedImage bi1 = ImageIO.read(bais);
    	File f1 = new File("d://out.png");
    	ImageIO.write(bi1, "png", f1);
    	} catch (IOException e) {
    	e.printStackTrace();
    	}
    }
    
    public ImageInfo getRGBData(File file) {
        if (file == null)
            return null;
        ImageInfo imageInfo;
        try {
            //将图片文件加载到内存缓冲区
            BufferedImage image = ImageIO.read(file);
            imageInfo = bufferedImage2ImageInfo(image);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return imageInfo;
    }

    private ImageInfo bufferedImage2ImageInfo(BufferedImage image) {
        ImageInfo imageInfo = new ImageInfo();
        int width = image.getWidth();
        int height = image.getHeight();
        // 使图片居中
        width = width & (~3);
        height = height & (~3);
        imageInfo.setWidth(width);
        imageInfo.setHeight(height);
        //根据原图片信息新建一个图片缓冲区
        BufferedImage resultImage = new BufferedImage(width, height, image.getType());
        //得到原图的rgb像素矩阵
        int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
        //将像素矩阵 绘制到新的图片缓冲区中
        resultImage.setRGB(0, 0, width, height, rgb, 0, width);
        //进行数据格式化为可用数据
        BufferedImage dstImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
            ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
            colorConvertOp.filter(resultImage, dstImage);
        } else {
            dstImage = resultImage;
        }
        //获取rgb数据
        imageInfo.setRgbData(((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData());
        return imageInfo;
    }


//    class ImageInfo {
//        public byte[] rgbData;
//        public int width;
//        public int height;
//
//        public byte[] getRgbData() {
//            return rgbData;
//        }
//
//        public void setRgbData(byte[] rgbData) {
//            this.rgbData = rgbData;
//        }
//
//        public int getWidth() {
//            return width;
//        }
//
//        public void setWidth(int width) {
//            this.width = width;
//        }
//
//        public int getHeight() {
//            return height;
//        }
//
//        public void setHeight(int height) {
//            this.height = height;
//        }
//    }
}
